home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / AECUR100.ARJ / CKBDINTF.C < prev    next >
C/C++ Source or Header  |  1991-11-04  |  10KB  |  366 lines

  1. /**********************************************************************
  2.  *  
  3.  *  ckbdintf.c
  4.  *
  5.  *  copyright (c) 1988,89,90,91 J. Alan Eldridge
  6.  *
  7.  *  C functions to interface to the PC keyboard BIOS
  8.  *  
  9.  *  11/02/91 JAE modified to work with GNU C++ (DJ Delorie's port)
  10.  *
  11.  *********************************************************************/
  12.  
  13. #include "curses.h"
  14.  
  15. #include "pckbscan.h"
  16.  
  17. #ifdef  __GNUC__
  18. #include    "aedef.h"
  19. #include    <pc.h>
  20. #define MSC50 0
  21. #define TURBOC 0
  22. #define AZTEC 0
  23. #endif
  24.  
  25. #if (MSC50 | TURBOC)
  26. #include <dos.h>
  27. #endif  /* (MSC50 | TURBOC) */
  28.  
  29. #if AZTEC
  30. #include "aztecdos.h"
  31. #endif  /* AZTEC */
  32.  
  33. /**********************************************************************
  34.  *  
  35.  *  useful constants
  36.  *  
  37.  *********************************************************************/
  38.  
  39. #define K_SYNONYM   64  /* size of synonym table (set to 0 to disable) */
  40.  
  41. #define KBD_INTR        0x16    /* ROM BIOS keyboard interrupt # */
  42. #define ZEROFLAG        0x40    /* mask to check CPU zero flag */
  43.  
  44. #define KBD_GET         0x00    /* standard kbd read function # */
  45. #define KBD_STATUS      0x01    /* standard kbd status function # */
  46.  
  47. #define EXT_KBD_GET     0x10    /* extended kbd read function # */
  48. #define EXT_KBD_STATUS  0x11    /* extended kbd status function # */
  49.  
  50. #define AT_MACHINE_ID   0xfc    /* ROM id code for AT and higher */
  51.  
  52. /**********************************************************************
  53.  *  
  54.  *  static variables
  55.  *  
  56.  *********************************************************************/
  57.  
  58. static  UCHAR   getfunc = KBD_GET;      /* BIOS function # to read chars */
  59. static  UCHAR   askfunc = KBD_STATUS;   /* BIOS function # for kb status */
  60.  
  61. #if K_SYNONYM
  62.  
  63. static int syncnt = 0;  /* cnt of entries in synonym table */
  64.  
  65. static struct {         /* map one key value to another */
  66.     int oldval;         /* value as originally mapped */
  67.     int newval;         /* new value to return instead */
  68. } syntable[K_SYNONYM];
  69.  
  70. #endif /* K_SYNONYM */
  71.  
  72. /* lookup table to map from BIOS to my key representation */
  73.  
  74. typedef struct {
  75.     int biosval;
  76.     int newval;
  77. } KEY_DEF;
  78.  
  79. #define NELEMS(arr) (sizeof(arr)/sizeof(arr[0]))
  80.  
  81. static KEY_DEF  keytable[] = {
  82.     /* unmodified keys */
  83.     { NULL_CHAR,    K_NULL  },
  84.     { FUNC_1,       K_F1    },
  85.     { FUNC_1 + 1,   K_F2    },
  86.     { FUNC_1 + 2,   K_F3    },
  87.     { FUNC_1 + 3,   K_F4    },
  88.     { FUNC_1 + 4,   K_F5    },
  89.     { FUNC_1 + 5,   K_F6    },
  90.     { FUNC_1 + 6,   K_F7    },
  91.     { FUNC_1 + 7,   K_F8    },
  92.     { FUNC_1 + 8,   K_F9    },
  93.     { FUNC_1 + 9,   K_F10   },
  94.     { FUNC_11,      K_F11   },
  95.     { FUNC_11 + 1,  K_F12   },
  96.     { HOME,         K_HOME  },
  97.     { UP,           K_UP    },
  98.     { PGUP,         K_PGUP  },
  99.     { LEFT,         K_LEFT  },
  100.     { RIGHT,        K_RIGHT },
  101.     { ENDKEY,       K_END   },
  102.     { DOWN,         K_DOWN  },
  103.     { PGDN,         K_PGDN  },
  104.     { INSRT,        K_INS   },
  105.     { DEL,          K_DEL   },
  106.     /* shift key down */
  107.     { FUNC_1S,      K_F1 | K_SHIFT  },
  108.     { FUNC_1S + 1,  K_F2 | K_SHIFT  },
  109.     { FUNC_1S + 2,  K_F3 | K_SHIFT  },
  110.     { FUNC_1S + 3,  K_F4 | K_SHIFT  },
  111.     { FUNC_1S + 4,  K_F5 | K_SHIFT  },
  112.     { FUNC_1S + 5,  K_F6 | K_SHIFT  },
  113.     { FUNC_1S + 6,  K_F7 | K_SHIFT  },
  114.     { FUNC_1S + 7,  K_F8 | K_SHIFT  },
  115.     { FUNC_1S + 8,  K_F9 | K_SHIFT  },
  116.     { FUNC_1S + 9,  K_F10 | K_SHIFT },
  117.     { FUNC_11S,     K_F11 | K_SHIFT },
  118.     { FUNC_11S + 1, K_F12 | K_SHIFT },
  119.     { SHIFT_TAB,    K_BACKTAB       },
  120.     /* alt key down */
  121.     { FUNC_1A,      K_F1 | K_ALT    },
  122.     { FUNC_1A + 1,  K_F2 | K_ALT    },
  123.     { FUNC_1A + 2,  K_F3 | K_ALT    },
  124.     { FUNC_1A + 3,  K_F4 | K_ALT    },
  125.     { FUNC_1A + 4,  K_F5 | K_ALT    },
  126.     { FUNC_1A + 5,  K_F6 | K_ALT    },
  127.     { FUNC_1A + 6,  K_F7 | K_ALT    },
  128.     { FUNC_1A + 7,  K_F8 | K_ALT    },
  129.     { FUNC_1A + 8,  K_F9 | K_ALT    },
  130.     { FUNC_1A + 9,  K_F10 | K_ALT   },
  131.     { FUNC_11A,     K_F11 | K_ALT   },
  132.     { FUNC_11A + 1, K_F12 | K_ALT   },
  133.     { ALT_A,        'a' | K_ALT     },
  134.     { ALT_B,        'b' | K_ALT     },
  135.     { ALT_C,        'c' | K_ALT     },
  136.     { ALT_D,        'd' | K_ALT     },
  137.     { ALT_E,        'e' | K_ALT     },
  138.     { ALT_F,        'f' | K_ALT     },
  139.     { ALT_G,        'g' | K_ALT     },
  140.     { ALT_H,        'h' | K_ALT     },
  141.     { ALT_I,        'i' | K_ALT     },
  142.     { ALT_J,        'j' | K_ALT     },
  143.     { ALT_K,        'k' | K_ALT     },
  144.     { ALT_L,        'l' | K_ALT     },
  145.     { ALT_M,        'm' | K_ALT     },
  146.     { ALT_N,        'n' | K_ALT     },
  147.     { ALT_O,        'o' | K_ALT     },
  148.     { ALT_P,        'p' | K_ALT     },
  149.     { ALT_Q,        'q' | K_ALT     },
  150.     { ALT_R,        'r' | K_ALT     },
  151.     { ALT_S,        's' | K_ALT     },
  152.     { ALT_T,        't' | K_ALT     },
  153.     { ALT_U,        'u' | K_ALT     },
  154.     { ALT_V,        'v' | K_ALT     },
  155.     { ALT_W,        'w' | K_ALT     },
  156.     { ALT_X,        'x' | K_ALT     },
  157.     { ALT_Y,        'y' | K_ALT     },
  158.     { ALT_Z,        'z' | K_ALT     },
  159.     { ALT_1,        '1' | K_ALT     },
  160.     { ALT_1 + 1,    '2' | K_ALT     },
  161.     { ALT_1 + 2,    '3' | K_ALT     },
  162.     { ALT_1 + 3,    '4' | K_ALT     },
  163.     { ALT_1 + 4,    '5' | K_ALT     },
  164.     { ALT_1 + 5,    '6' | K_ALT     },
  165.     { ALT_1 + 6,    '7' | K_ALT     },
  166.     { ALT_1 + 7,    '8' | K_ALT     },
  167.     { ALT_1 + 8,    '9' | K_ALT     },
  168.     { ALT_1 + 9,    '0' | K_ALT     },
  169.     { ALT_MINUS,    '-' | K_ALT     },
  170.     { ALT_EQUAL,    '=' | K_ALT     },
  171.     /* control key down */
  172.     { FUNC_1C,      K_F1 | K_CTL    },
  173.     { FUNC_1C + 1,  K_F2 | K_CTL    },
  174.     { FUNC_1C + 2,  K_F3 | K_CTL    },
  175.     { FUNC_1C + 3,  K_F4 | K_CTL    },
  176.     { FUNC_1C + 4,  K_F5 | K_CTL    },
  177.     { FUNC_1C + 5,  K_F6 | K_CTL    },
  178.     { FUNC_1C + 6,  K_F7 | K_CTL    },
  179.     { FUNC_1C + 7,  K_F8 | K_CTL    },
  180.     { FUNC_1C + 8,  K_F9 | K_CTL    },
  181.     { FUNC_1C + 9,  K_F10 | K_CTL   },
  182.     { FUNC_11C,     K_F11 | K_CTL   },
  183.     { FUNC_11C + 1, K_F12 | K_CTL   },
  184.     { C_PRTSC,      K_PRTSC | K_CTL },
  185.     { C_LEFT,       K_LEFT  | K_CTL },
  186.     { C_RIGHT,      K_RIGHT | K_CTL },
  187.     { C_END,        K_END   | K_CTL },
  188.     { C_PGDN,       K_PGDN  | K_CTL },
  189.     { C_HOME,       K_HOME  | K_CTL },
  190.     { C_PGUP,       K_PGUP  | K_CTL }
  191. };
  192.     
  193. #define KEYTBL_SIZE NELEMS(keytable)
  194.  
  195. /**********************************************************************
  196.  * 
  197.  *  _kb_init()
  198.  *  
  199.  *  initialize the keyboard interface
  200.  *  
  201.  *  no harm will come if this is not called, but certain keys
  202.  *  on the AT (e.g., F11 and F12) cannot be read otherwise
  203.  *  
  204.  *********************************************************************/
  205.  
  206. void
  207. _kb_init(void)
  208. {
  209. #ifndef __GNUC__
  210.     if (__MACHID.model == AT_MACHINE_ID) {
  211.         /* if it's an AT type machine or higher ... */
  212.         if (__MACHID.submodel) {  /* if it's not submodel 0 ... */
  213.             getfunc = EXT_KBD_GET;      /* we can use extended kb  ... */
  214.             askfunc = EXT_KBD_STATUS;   /* read and status functions */
  215.         }
  216.     }
  217. #endif
  218. }
  219.  
  220. /**********************************************************************
  221.  *  
  222.  *  _kb_read()
  223.  *  
  224.  *  get a character from the BIOS
  225.  *  
  226.  *********************************************************************/
  227.  
  228. int
  229. _kb_read(void)
  230. {
  231. #ifndef __GNUC__
  232.     union REGS  reg_st;
  233.     
  234.     reg_st.h.ah = getfunc;
  235.     int86(KBD_INTR, ®_st, ®_st);
  236.     return reg_st.x.ax;
  237. #else
  238.     int c = getxkey();
  239.     if (c > 255) {
  240.         unsigned char ah = c >> 8;
  241.         unsigned char al = c & 0xff;
  242.         
  243.         ah = (ah == 1) ? 0 : 0xE0;
  244.         
  245.         c = ah | (al << 8);
  246.     }
  247.     return c;
  248. #endif    
  249. }    
  250.  
  251. /**********************************************************************
  252.  *  
  253.  *  _kb_look()
  254.  *  
  255.  *  returns 1 if there's a character waiting, 0 if not
  256.  *  
  257.  *********************************************************************/
  258.  
  259. int
  260. _kb_look(void)
  261. {
  262. #ifndef __GNUC__
  263.     union REGS  reg_st;
  264.     
  265.     reg_st.h.ah = askfunc;
  266. #if TURBOC
  267.     int86(KBD_INTR, ®_st, ®_st);
  268.     return !(reg_st.x.flags & ZEROFLAG);
  269. #endif  /* TURBOC */
  270. #if AZTEC
  271.     return !(int86(KBD_INTR, ®_st, ®_st) & ZEROFLAG);
  272. #endif  /* AZTEC */
  273. #if MSC50
  274.     return _bios_keybrd(askfunc) != 0;
  275. #endif  /* MSC50 */
  276. #else
  277.     return kbhit();
  278. #endif
  279. }
  280.  
  281. #if K_SYNONYM
  282.  
  283. /**********************************************************************
  284.  *  
  285.  *  _kb_syn(oldval, newval)
  286.  *  
  287.  *  creates a "synonym" for a key
  288.  *  
  289.  *  if oldval would have been returned, return newval instead
  290.  *  
  291.  *********************************************************************/
  292.  
  293. int
  294. _kb_syn(
  295.     int oldval,
  296.     int newval)
  297. {
  298.     if (syncnt < K_SYNONYM) {
  299.         syntable[syncnt].oldval = oldval;
  300.         syntable[syncnt++].newval = newval;
  301.         return 0;
  302.     } else
  303.         return -1;
  304. }
  305.  
  306. static int
  307. synxlat(int oldval)
  308. {
  309.     int n;
  310.     
  311.     for (n = 0; n < syncnt; n++) 
  312.         if (syntable[n].oldval == oldval)
  313.             return syntable[n].newval;
  314.  
  315.     return oldval;
  316. }
  317.  
  318. #else
  319.  
  320. #define synxlat(c)  c   /* make this a no-op */
  321.  
  322. #endif  /* K_SYNONYM */
  323.  
  324. /**********************************************************************
  325.  *  
  326.  *  _kb_mapc(c)
  327.  *  
  328.  *  given a key code returned by the BIOS, return the Curses!
  329.  *  representation of that key, translating a synonym if found
  330.  *  
  331.  *  a key that doesn't make sense is mapped to K_UNKNOWN
  332.  *  
  333.  *********************************************************************/
  334.  
  335. int
  336. _kb_mapc(int c)
  337. {
  338.     int al = c & 0xff;
  339.     int ah = (unsigned int)c >> 8;
  340.     
  341.     if (al == 0x00 || al == 0xe0) {
  342.         int n; 
  343.         
  344.         for (n = 0; n < KEYTBL_SIZE; n++)
  345.             if (keytable[n].biosval == ah)
  346.                 return synxlat(keytable[n].newval);
  347.  
  348.         return K_UNKNOWN;
  349.     } else
  350.         return al;
  351. }
  352.  
  353. /**********************************************************************
  354.  *  
  355.  *  _kb_getc()
  356.  *  
  357.  *  low level keyboard call that does character mapping
  358.  *  
  359.  *********************************************************************/
  360.  
  361. int
  362. _kb_getc(void)
  363. {
  364.     return _kb_mapc(_kb_read());
  365. }
  366.